package com.jrx.anytxn.accounting.service.impl;

import com.jrx.anytxn.accounting.bean.GlInterfaceBean;
import com.jrx.anytxn.accounting.constant.AccountBizConstant;
import com.jrx.anytxn.accounting.entity.GaVoucherInfo;
import com.jrx.anytxn.accounting.entity.TlGlInterfaceInfoExcpReport;
import com.jrx.anytxn.accounting.service.ITlGlInterfaceInfoService;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.customer.entity.CmCustomerExtInfo;
import com.jrx.anytxn.customer.mapper.ext.ExtCmCustomerExtInfoMapper;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.dto.aviator.RuleMatchReq;
import com.jrx.anytxn.param.entity.GaSubjectAccountConfig;
import com.jrx.anytxn.param.service.account.ISubjectAccountConfigService;
import com.jrx.anytxn.param.service.aviator.IAviatorService;
import com.jrx.anytxn.param.utils.BizTypeProducts;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.TlGlInterfaceInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 总账流水处理过程
 *
 * @author yf
 * @version 1.0
 * @date 2019/10/23
 */
@Service
public class TlGlInterfaceInfoServiceImpl implements ITlGlInterfaceInfoService {

    @Autowired
    private IAviatorService aviatorService;
    @Autowired
    private ISegmentService iSegmentService;
    @Autowired
    private ISubjectAccountConfigService subjectAccountConfigService;
    @Autowired
    private ExtCmCustomerExtInfoMapper extCmCustomerExtInfoMapper;

    @Override
    public GlInterfaceBean getGlInterfaceBean(TlGlInterfaceInfo tlGlInterfaceInfo) throws Exception {
        GlInterfaceBean glInterfaceBean = new GlInterfaceBean();
        List<TlGlInterfaceInfoExcpReport> list = new ArrayList<>();
        List<GaVoucherInfo> voucherInfoList = new ArrayList<>();

        //执行规则，获取规则结果
        Map map = new HashMap();
        //会计拆分规则条件
        map.put("organizationId", tlGlInterfaceInfo.getOrganizationId());
        map.put("txnCode", tlGlInterfaceInfo.getTxnCode());
        map.put("loanProductId", tlGlInterfaceInfo.getLoanProductId());
        map.put("loanClassify", tlGlInterfaceInfo.getLoanClassify());
        map.put("category", tlGlInterfaceInfo.getCategory());
        map.put("channel", tlGlInterfaceInfo.getChannel());
        map.put("totalTenor", tlGlInterfaceInfo.getAttributeReserve1());
        map.put("totalDays", tlGlInterfaceInfo.getAttributeReserve2());
        map.put("accountStatus", tlGlInterfaceInfo.getAttributeReserve3());
        map.put("liabilityFlag", tlGlInterfaceInfo.getLiabilityFlag());
        map.put("bankType", tlGlInterfaceInfo.getBankType());
        //执行会计核算规则
        RuleMatchReq ruleMatchReq = new RuleMatchReq(tlGlInterfaceInfo.getOrganizationId(), null,
                TransBizConstant.VOUCHER_RULE_SET, map, tlGlInterfaceInfo.getTenantId());
        //获取所有的会计核算结果信息
        List<Map<String, Object>> resultMapList = aviatorService.executeRuleList(ruleMatchReq);
        //没有匹配的规则，加入到总账流水例外表中
        if (CollectionUtils.isEmpty(resultMapList)) {
            TlGlInterfaceInfoExcpReport tlGlInterfaceInfoExcpReport=new TlGlInterfaceInfoExcpReport();
            BeanUtils.copyProperties(tlGlInterfaceInfo, tlGlInterfaceInfoExcpReport);
            list.add(tlGlInterfaceInfoExcpReport);
            glInterfaceBean.setTlGlInterfaceInfoExcpReportList(list);
            return glInterfaceBean;
        }
        int count = 0;
        for (Map<String, Object> resultMap : resultMapList) {
            List<GaVoucherInfo> gaVoucherInfoList = this.getByConditions(resultMap, tlGlInterfaceInfo, count);
            List<String> subjectIdList = (List<String>) resultMap.get(AccountBizConstant.RULE_RESULT_SUBJECT);
            count = count + subjectIdList.size();
            voucherInfoList.addAll(gaVoucherInfoList);
        }
        glInterfaceBean.setVoucherInfoList(voucherInfoList);

        return glInterfaceBean;
    }

    private List<GaVoucherInfo> getByConditions(Map<String, Object> resultMap, TlGlInterfaceInfo info, Integer count) throws Exception {
        List<GaVoucherInfo> voucherInfoList = new ArrayList<>();
        List<String> subjectIdList = (List<String>) resultMap.get(AccountBizConstant.RULE_RESULT_SUBJECT);
        String conOrgId = String.valueOf(resultMap.get(AccountBizConstant.RULE_RESULT_CON_ORG_ID));
        int subjectCount = 0;
        for (String subjectId : subjectIdList) {
            subjectCount++;
            //创建传票流水
            GaVoucherInfo voucherInfo = new GaVoucherInfo();
            voucherInfo.setId(iSegmentService.getId(AccountBizConstant.TABLE_VOUCHERINFO));
            voucherInfo.setTenantId(info.getTenantId());
            voucherInfo.setOrganizationId(info.getOrganizationId());
            voucherInfo.setBusinessDate(info.getGlDate());
            voucherInfo.setFlowno(info.getGlFlowno());
            voucherInfo.setSeq(count + subjectCount);

            //查询科目产品内部户映射配置
            GaSubjectAccountConfig subjectAccountConfig = subjectAccountConfigService.findBySubjectIdAndProductId(subjectId,info.getTenantId(),info.getLoanProductId());
            if(subjectAccountConfig!=null){
                //若科目+产品  有对应的内部户配置   则使用内部户账号生成传票
                subjectId = subjectAccountConfig.getInnerAccount();
            }

            voucherInfo.setSubjectId(subjectId);
            voucherInfo.setSign((String) resultMap.get(AccountBizConstant.RULE_RESULT_VOUCHERINFOSIGN));
            //红字R为负，蓝字B正
            if (AccountBizConstant.SIGN_RED.equals(resultMap.get(AccountBizConstant.RULE_RESULT_SIGN))) {
                voucherInfo.setAmount(info.getAmount().negate());
            } else {
                voucherInfo.setAmount(info.getAmount());
            }
            voucherInfo.setTxnCode(info.getTxnCode());
            //币种
            voucherInfo.setCurrency(AccountBizConstant.CURRENCY);
            voucherInfo.setLoanId(info.getLoanId());
            voucherInfo.setCustomerId(info.getCustomerId());
            voucherInfo.setAccountId(info.getTxnAccountId());
            voucherInfo.setDescription(info.getTxnDesc());
            //传票类型-->更新科目总账
            voucherInfo.setVoucherType(TransBizConstant.TYPE_G);
            //传票来源--> 核心账务组件
            voucherInfo.setSrc(TransBizConstant.SRC_C);
            voucherInfo.setProductId(info.getLoanProductId());
            voucherInfo.setChannel(info.getChannel());
            voucherInfo.setLoanClassify(info.getLoanClassify());
            voucherInfo.setCategory(info.getCategory());
            voucherInfo.setUpdateBy(AccountBizConstant.USER_NAME);
            voucherInfo.setRecordVersionNumber(1);
            voucherInfo.setInvestorId(TransBizConstant.DEFAULT_INNER_INVESTOR_ID);
            String feeCode=String.valueOf(resultMap.get(AccountBizConstant.RULE_RESULT_FEE_CODE));
            if(StringUtils.isNotBlank(feeCode)){
                voucherInfo.setPriceTxaCode(feeCode);
                if(StringUtils.isNotBlank(info.getAttributeReserve4())){
                    voucherInfo.setSalesAmt(new BigDecimal(info.getAttributeReserve4()));
                }else {
                    voucherInfo.setSalesAmt(BigDecimal.ZERO);
                }
            }else{
                voucherInfo.setPriceTxaCode("");
                voucherInfo.setSalesAmt(BigDecimal.ZERO);
            }
            voucherInfo.setSubChannel(info.getSubChannel());
            voucherInfo.setConOrgId(this.getConOrgId(voucherInfo.getCustomerId(), voucherInfo.getTenantId(), conOrgId, info.getLoanProductId()));

            voucherInfoList.add(voucherInfo);
        }
        return voucherInfoList;
    }

    /**
     * 获取并账机构
     *
     * @param customerId 客户id
     * @param tenantId   租户id
     * @param conOrgId   并账机构
     * @param productId  产品编号
     * @return String
     */
    private String getConOrgId(String customerId, String tenantId,String conOrgId,String productId) throws TxnBizException {
        String bankOrgNo = conOrgId;
        if (StringUtils.isBlank(conOrgId)) {
            // 修改客户客群
            List<CmCustomerExtInfo> cmCustomerExtInfos = extCmCustomerExtInfoMapper.queryCustomerExtInfos(customerId, tenantId, BizTypeProducts.getSymbolProductId(productId));
            if (!CollectionUtils.isEmpty(cmCustomerExtInfos)) {
                //获取客户二级信息所属机构号
                bankOrgNo = cmCustomerExtInfos.get(0).getBankOrgNo();
            }
        }
        return bankOrgNo;
    }
}